import hashlib
import numpy as np
from numpy.random import default_rng
import matplotlib.pyplot as plt

# 密钥流产生器
# PLM 映射函数
# num_segments：分段的段数，控制系统的混沌程度和分段的粒度。
def piecewise_logistic_map(x, r, n,d):
    segment_length = 1.0 / n
    # print(j)
    a = ""
    for i in range(n):
        left_segment = (i - 1) * segment_length
        min_segment = i * segment_length
        right_segment = (i + 1) * segment_length
        x_d = x / d
        if x_d > left_segment and  x_d <= min_segment:
            x = ((r * (n * x - d * (i - 1)) * (d * i - n * x))) / d   
            break
        elif x_d >= min_segment and  x_d <= right_segment:
            x = d - ((r * (n * x - d * i) * (d * (i + 1) - n * x))) / d
            break
    return x

# generate_key函数是生成密钥的函数，其参数包括：
# seed_str：种子值，用于初始化Logistic映射的状态值。
def generate_key_stream(seed_str, r, n, key_length,d):
    key = []
    x = key_to_hash(seed_str) * (d + 1)
    # x = 10
    print("x:"+str(x))
    for j in range(key_length):
        x = piecewise_logistic_map(x, r, n,d)
        # key.append(int(x * 10000) % 256) # 取最后两位小数作为密钥的一个字节
        key.append(x)
    return key
 
#  密钥获取hash函数
def key_to_hash(seed_str):
    # 计算字符串的哈希值
    sha256 = hashlib.sha256(seed_str.encode()).digest()
    # 使用哈希值作为种子
    rng = default_rng(int.from_bytes(sha256, "big"))
    # 生成随机数
    r = rng.random()
    # 保留两位小数
    r = np.round(r, decimals=2)
    # 输出结果
    return r


if __name__ == '__main__':
    seed_str = "this is a key" #密钥key
    u = 4         #迭代状态值u->(0,4)
    n = 64            #映射的分段总数
    d = 255
    key_length = 50  # key_length：生成的密钥长度，单位为字节
    key = generate_key_stream(seed_str, u, n, key_length,d)
    # key_arr = [format(i, '03d') for i in key]
    print("key stream:",key)





   




